home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr10 / inter35c.zip / INTLIST.E < prev    next >
Text File  |  1993-06-04  |  25KB  |  895 lines

  1. /****************************************************************/
  2. /*    EEL code file for editing the Interrupt List        */
  3. /*                                */
  4. /*    Written by Ralf Brown                    */
  5. /*    LastEdit:  3 Jun 93                    */
  6. /*                                */
  7. /*  This EEL file adds the following keybindings:        */
  8. /*    Shf-Alt-B add another BUG: to the current entry           */
  9. /*    Shf-Alt-D add a Desc: section to the current entry    */
  10. /*    Alt-I    add an Index: section to the current entry    */
  11. /*        add another Index: line if already on Index:    */
  12. /*      Alt-N   add a new note to current entry or data struct  */
  13. /*      Alt-P   add a Program: section to the current entry     */
  14. /*      Alt-R   insert Return: at start of line                 */
  15. /*    Alt-S    insert SeeAlso: at start of line        */
  16. /*    F11    insert a blank separator line            */
  17. /*    ^F11    create Format of: header            */
  18. /*    Shf-F11    create Values for: header            */
  19. /*    Alt-F11 create Call with: header            */
  20. /*    Alt-F12 create Bitfield for: header            */
  21. /*    F12    add the interrupt number to the separator line    */
  22. /*        preceding the current entry            */
  23. /*    ^F12    jump to a specified entry            */
  24. /*                                */
  25. /*  Other:                            */
  26. /*    adds intlist-mode for .LST and .1ST files        */
  27. /*    switches current buffer into intlist-mode on loading    */
  28. /****************************************************************/
  29.  
  30. #include "eel.h"
  31.  
  32. keytable intlist_tab ;            /* key table for IntList mode */
  33.  
  34. /*=============================================================*/
  35. /*=============================================================*/
  36.  
  37. char return_section[] = "Return: " ;
  38. char program_section[] = "Program: " ;
  39. char desc_section[] = "Desc:\t" ;
  40. char notes_section[] = "Notes*:\t" ;
  41. char bugs_section[] = "BUGS*:\t" ;
  42. char seealso_section[] = "SeeAlso: " ;
  43. char index_section[] = "Index:\t" ;
  44.  
  45. /*=============================================================*/
  46. /*=============================================================*/
  47.  
  48. int empty_line()
  49. {
  50.    return (character(point-1) == '\n' && character(point) == '\n') ;
  51. }
  52.  
  53. /*=============================================================*/
  54. /*=============================================================*/
  55.  
  56. int is_separator_line()
  57. {
  58.    return (empty_line() || parse_string(1,"--------",NULL)) ;
  59. }
  60.  
  61. /*=============================================================*/
  62. /* search in the specified direction (1 = forward, -1 = back)  */
  63. /* for the next entry separator line                   */
  64. /*=============================================================*/
  65.  
  66. int to_separator_line(dir)
  67. int dir ;
  68. {
  69.    return search(dir,"\n--------") ;
  70. }
  71.  
  72. /*=============================================================*/
  73. /* move to the location where the specified section of an      */
  74. /* entry begins (if present) or should begin (if not)           */
  75. /*=============================================================*/
  76.  
  77. int to_section_start(section)
  78. char *section ;
  79. {
  80.    int i, j, len ;
  81.    char *(sections[8]) ;
  82.  
  83.    /* list the sections of an entry in the order they should appear (if */
  84.    /* present at all) */
  85.    sections[0] = return_section ;
  86.    sections[1] = program_section ;
  87.    sections[2] = desc_section ;
  88.    sections[3] = notes_section ;
  89.    sections[4] = bugs_section ;
  90.    sections[5] = seealso_section ;
  91.    sections[6] = index_section ;
  92.    sections[7] = NULL ;
  93.    for (i = 0 ; sections[i] ; i++)
  94.       if (strcmp(section,sections[i]) == 0)
  95.      break ;
  96.    if (sections[i])
  97.       {
  98.       while (!is_separator_line() && !empty_line())
  99.      {
  100.      for (j = i ; sections[j] ; j++)
  101.         if (parse_string(1,sections[j],NULL))
  102.            {
  103.            if ((len = parse_string(1,section,NULL)) != 0)
  104.           {
  105.           point += len ;
  106.           return 1 ;    /* section already exists */
  107.           }
  108.            return 0 ;    /* section nonexistent, but found position */
  109.            }
  110.      if (!nl_forward())
  111.         break ;
  112.      }
  113.       return 0 ;    /* section does not yet exist */
  114.       }
  115.    else
  116.       return 0 ;    /* section not found */
  117. }
  118.  
  119. /*=============================================================*/
  120. /*=============================================================*/
  121.  
  122. int make_section(section,start_entry,name)
  123. char *section, *name ;
  124. int start_entry ;
  125. {
  126.    int start = point ;
  127.  
  128.    if (start_entry)
  129.       {
  130.       if (!to_separator_line(-1))  /* find previous separator line */
  131.      {
  132.      point = start ;
  133.      say("Not in an interrupt entry") ;
  134.      return 0 ;
  135.      }
  136.       }
  137.    else
  138.       {
  139.       to_begin_line() ;
  140.       while (!empty_line() && !parse_string(1,"\n--------",NULL))
  141.      if (!nl_reverse())
  142.         break ;
  143.       }
  144.    point++ ;                 /* skip the newline */
  145.    nl_forward() ;             /* advance to first line of entry */
  146.    if (!to_section_start(section))
  147.       {
  148.       if (name)
  149.      stuff(name) ;
  150.       else
  151.      stuff(section) ;
  152.       stuff("\n") ;
  153.       point-- ;              /* back up over inserted newline */
  154.       return 1 ;
  155.       }
  156.    else
  157.       return 0 ;
  158.    return 2 ;  /* just in case */
  159. }
  160.  
  161. /*=============================================================*/
  162. /*=============================================================*/
  163.  
  164. int pluralize_section(plural)
  165. char plural ;
  166. {
  167.    point -= 3 ;
  168.    if (curchar() != plural)        /* already plural ? */
  169.       {
  170.       point++ ;
  171.       insert(plural) ;
  172.       }
  173.    nl_forward() ;
  174.    while (!is_separator_line() && parse_string(1,"[ \t]",NULL))
  175.       nl_forward() ;
  176.    stuff("\t\n") ;
  177.    point-- ;
  178. }
  179.  
  180. /*=============================================================*/
  181. /* Add "SeeAlso: " to the beginning of the current line unless */
  182. /* it is already present                       */
  183. /*=============================================================*/
  184.  
  185. command see_also() on intlist_tab[ALT('s')]
  186. {
  187.    to_begin_line() ;
  188.    if (parse_string(1,"SeeAlso: ",NULL) == 0)
  189.       stuff("SeeAlso: ") ;
  190.    else
  191.       {
  192.       nl_forward() ;
  193.       stuff("SeeAlso: \n") ;
  194.       point-- ;
  195.       }
  196. }
  197.  
  198. /*=============================================================*/
  199. /* Add a Desc: section if the current entry does not already   */
  200. /* have one; if there is already a Desc: section, move to the  */
  201. /* start of it                               */
  202. /*=============================================================*/
  203.  
  204. command desc() on intlist_tab[ALT('D')]
  205. {
  206.    make_section(desc_section,1,NULL) ;
  207. }
  208.  
  209. /*=============================================================*/
  210. /* Add a "Program: " section to the current entry if it does   */
  211. /* not have one; otherwise, move to the beginning of the       */
  212. /* Program: section                           */
  213. /*=============================================================*/
  214.  
  215. command program() on intlist_tab[ALT('p')]
  216. {
  217.    make_section(program_section,1,NULL) ;
  218. }
  219.  
  220. /*=============================================================*/
  221. /* Add an "Index: " section to the current entry if it does    */
  222. /* not have one; otherwise, move to the beginning of the       */
  223. /* Index: section                           */
  224. /*=============================================================*/
  225.  
  226. command add_index() on intlist_tab[ALT('i')]
  227. {
  228.    to_begin_line() ;
  229.    if (parse_string(1,"Index:",NULL))
  230.       {
  231.       while (parse_string(1,"Index:",NULL))
  232.      nl_forward() ;
  233.       stuff("Index:\t\n") ;
  234.       point-- ;
  235.       }
  236.    else
  237.       make_section(index_section,1,NULL) ;
  238. }
  239.  
  240. /*=============================================================*/
  241. /*=============================================================*/
  242.  
  243. command bug() on intlist_tab[ALT('B')]
  244. {
  245.    if (!make_section(bugs_section,1,"BUG:\t"))
  246.       pluralize_section('S') ;
  247. }
  248.  
  249. /*=============================================================*/
  250. /* Add "Note: " section to the current entry; change an        */
  251. /* existing Note: to Notes: and position at end of Note:       */
  252. /* section.                               */
  253. /*=============================================================*/
  254.  
  255. command add_note() on intlist_tab[ALT('n')]
  256. {
  257.    if (!make_section(notes_section,0,"Note:\t"))
  258.       pluralize_section('s') ;
  259. }
  260.  
  261. /*=============================================================*/
  262. /* Insert "Return: " at the beginning of the current line, if  */
  263. /* not already present                           */
  264. /*=============================================================*/
  265.  
  266. command returns() on intlist_tab[ALT('r')]
  267. {
  268.    int start = point ;
  269.    
  270.    to_begin_line() ;
  271.    if (parse_string(1,return_section,NULL) == 0)
  272.       stuff(return_section) ;
  273.    else
  274.       point = start ;
  275. }
  276.  
  277. /*=============================================================*/
  278. /* insert a line of dashes prior to the current cursor line    */
  279. /*=============================================================*/
  280.  
  281. command separator_line() on intlist_tab[FKEY(11)]
  282. {
  283.    int i ;
  284.  
  285.    to_begin_line() ;
  286.    for (i = 0 ; i < 45 ; i++)
  287.       insert('-') ;
  288.    insert('\n') ;
  289. }
  290.  
  291. /*=============================================================*/
  292. /* type the name of a structure, then invoke this function     */
  293. /* to create the "Format of X:" and "Offset Size Descr" lines  */
  294. /*=============================================================*/
  295.  
  296. command structure_header() on intlist_tab[FCTRL(11)]
  297. {
  298.    int start = point ;
  299.  
  300.    to_begin_line() ;
  301.    if (parse_string(1,"Format of ",NULL) == 0)
  302.       {
  303.       stuff("Format of ") ;
  304.       to_end_line() ;
  305.       stuff(":\nOffset\tSize\tDescription\n 00h\t") ;
  306.       }
  307.    else
  308.       point = start ;
  309. }
  310.  
  311. /*=============================================================*/
  312. /* Turn the current line into the header for a "Values of"     */
  313. /* section                               */
  314. /*=============================================================*/
  315.  
  316. command value_header() on intlist_tab[FSHIFT(11)]
  317. {
  318.    int start = point ;
  319.    
  320.    to_begin_line() ;
  321.    if (parse_string(1,"Values for ",NULL) == 0)
  322.       {
  323.       stuff("Values for ") ;
  324.       to_end_line() ;
  325.       stuff(":\n ") ;
  326.       }
  327.    else
  328.       point = start ;
  329. }
  330.  
  331. /*=============================================================*/
  332. /* Turn the current line into the header of a "Call with"      */
  333. /* section                               */
  334. /*=============================================================*/
  335.  
  336. command call_with_header() on intlist_tab[FALT(11)]
  337. {
  338.    int start = point ;
  339.    
  340.    to_begin_line() ;
  341.    if (parse_string(1,"Call ",NULL) == 0)
  342.       {
  343.       stuff("Call ") ;
  344.       to_end_line() ;
  345.       stuff("with:\n") ;
  346.       }
  347.    else
  348.       point = start ;
  349. }
  350.  
  351. /*=============================================================*/
  352. /* Turn the current line into the header of a "Bitfield for"   */
  353. /* section                               */
  354. /*=============================================================*/
  355.  
  356. command bitfields_for_header() on intlist_tab[FALT(12)]
  357. {
  358.    int start = point ;
  359.    
  360.    to_begin_line() ;
  361.    if (parse_string(1,"Bitfields for ",NULL) == 0)
  362.       {
  363.       stuff("Bitfields for ") ;
  364.       to_end_line() ;
  365.       stuff(":\n") ;
  366.       }
  367.    else
  368.       point = start ;
  369. }
  370.  
  371. /*=============================================================*/
  372. /*=============================================================*/
  373.  
  374. char grab_entry_number(func_num)
  375. char *func_num ;
  376. {
  377.    char c ;
  378.    int i ;
  379.  
  380.    strcpy(func_num,"------------") ;    /* 12 dashes */
  381.    point++ ;                /* go to first char of separator line */
  382.    nl_forward() ;            /* go to first line of entry */
  383.    if (parse_string(1,"INT ",NULL) == 0)
  384.       return 0 ;            /* not an interrupt entry, so return */
  385.    point += 4 ;                /* skip the "INT " */
  386.    func_num[0] = curchar() ;        /* grab the interrupt number */
  387.    point++ ;
  388.    func_num[1] = curchar() ;
  389.    nl_forward() ;            /* skip to second line of entry */
  390.    if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
  391.       {
  392.       re_search(1,"[ \t]*A") ;
  393.       c = curchar() ;
  394.       point += 4 ;            /* skip ch and " = " */
  395.       if (c != 'L')
  396.      {
  397.      grab(point,point+((c=='X')?4:2),func_num+2) ;
  398.      point += ((c=='X')?4:2) ;
  399.      func_num[(c=='H')?4:6] = '-' ;    /* grab() stuck a NUL into the string */
  400.      }
  401.       else /* c == 'L' */
  402.      {
  403.      func_num[4] = curchar() ;
  404.      point++ ;
  405.      func_num[5] = curchar() ;
  406.      point ++ ;
  407.      }
  408.       point++ ;
  409.       if (parse_string(1,"[ \t]*subfn [0-9A-F][0-9A-F]+h",NULL))
  410.      {
  411.      re_search(1,"[ \t]*subfn ") ;
  412.      func_num[6] = 'S' ;
  413.      func_num[7] = 'F' ;
  414.      for (i = 0 ; i < 4 ; i++)
  415.         {
  416.         c = curchar() ;
  417.         if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
  418.            {
  419.            func_num[8+i] = c ;
  420.            point++ ;
  421.            }
  422.         else
  423.            break ;
  424.         }
  425.      }
  426.       nl_forward() ;            /* skip to third line of entry */
  427.       }
  428.    if (parse_string(1,"[ \t]*[BCDES][HILPSX] = [0-9A-F][0-9A-F]+h",NULL))
  429.       {
  430.       re_search(1,"[ \t]*") ;
  431.       func_num[6] = curchar() ;
  432.       point++ ;
  433.       func_num[7] = c = curchar() ;
  434.       point += 4 ;            /* skip curchar and " = " */
  435.       if (c == 'H' || c == 'L')
  436.      {
  437.      grab(point,point+2,func_num+8) ;
  438.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  439.      }
  440.       else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
  441.      grab(point,point+4,func_num+8) ;
  442.       }
  443.    return 1 ;                /* successful and have func number */
  444. }
  445.  
  446. /*=============================================================*/
  447. /* Put the interrupt and function number into the separator    */
  448. /* line just above the intlist entry preceding the cursor pos  */
  449. /*=============================================================*/
  450.  
  451. int number_one_int()
  452. {
  453.    char func_num[13] ;            /* 2->int, 4->AX, 6->extra reg, NUL */
  454.    int oldpoint ;
  455.    
  456.    while (to_separator_line(-1))    /* find previous separator line */
  457.       {
  458.       oldpoint = point ;
  459.       if (grab_entry_number(func_num))    /* does it belong to an intlist entry? */
  460.      {                /*   if yes, success, else try again */
  461.      point = oldpoint + 11 ;    /* skip NL and first ten dashes */
  462.      delete(point,point+12) ;    /* replace 12 dashes by the function */
  463.      stuff(func_num) ;        /*   number and extra register */
  464.      point = oldpoint ;        /* back to start of line, allowing repeat */
  465.      return 1 ;
  466.      }
  467.       point = oldpoint ;
  468.       }
  469.    return 0 ;                /* if we get here, we failed */
  470. }
  471.  
  472. /*=============================================================*/
  473. /* Put the interrupt and function number into the separator    */
  474. /* line just above one or more intlist entries preceding the   */
  475. /* current cursor position, letting user know of progress      */
  476. /*=============================================================*/
  477.  
  478. command number_int() on intlist_tab[FKEY(12)]
  479. {
  480.    int i, hit_top = 0 ;
  481.    
  482.    for (i = 0 ; i < iter ; i++)
  483.       {
  484.       if (!number_one_int())
  485.      {
  486.      hit_top = 1 ;
  487.      say("No prior entry.") ;
  488.      break ;
  489.      }
  490.       if (((i+1) % 100) == 0)
  491.      say("%d...",i+1) ;
  492.       }
  493.    if (iter > 1 && !hit_top)
  494.       say("Done.") ;
  495.    iter = 1 ;
  496. }
  497.  
  498. /*=============================================================*/
  499. /*=============================================================*/
  500.  
  501. int line_has_see_also()
  502. {
  503.    int len ;
  504.    
  505.    to_begin_line() ;
  506.    if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
  507.       {
  508.       point += len ;        /* go to start of cross-reference */
  509.       point += parse_string(1,"also ",NULL) ;
  510.       if (parse_string(1,"INT [0-9A-F]",NULL) ||
  511.       parse_string(1,"A[XHL] =",NULL)
  512.      )
  513.      {
  514.      point++ ;        /* move into reference */
  515.      return 1 ;
  516.      }
  517.       }
  518.    return 0 ;
  519. }
  520.  
  521. /*=============================================================*/
  522. /*=============================================================*/
  523.  
  524. int grab_int_reference(ref)
  525. char *ref ;
  526. {
  527.    int begin, start = point ;
  528.    
  529.    re_search(-1,"[, \t\n]") ;    /* backup to start of reference */
  530.    if (curchar() == '\n')    /* start of line? */
  531.       re_search(1,":[ \t]") ;    /* skip the SeeAlso: */
  532.    else if (character(point-1) == 'T' && character(point-2) == 'N')
  533.       point -= 3 ;
  534.    else
  535.       point++ ;            /* back to start of reference */
  536.    begin = point ;
  537.    re_search(1,"[,\n\"]") ;    /* find end of INT-spec */
  538.    point-- ;
  539.    if (curchar() == '\"')    /* extra string at end of INT-spec? */
  540.       {
  541.       point++ ;
  542.       re_search(1,"[\"\n]") ;    /* if yes, run to end of line or string */
  543.       }
  544.    grab(begin,point,ref) ;
  545.    point = start ;
  546.    return 0 ;
  547. }
  548.  
  549. /*=============================================================*/
  550. /*=============================================================*/
  551.  
  552. int parse_int_name(entry_name,id,extra_string)
  553. char *entry_name, *id, *extra_string ;
  554. {
  555.    int start = point ;
  556.    int i ;
  557.    char c, *last ;
  558.  
  559.    for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
  560.       entry_name[i] = toupper(entry_name[i]) ;
  561.    strcpy(id,"------------") ;
  562.    if (strncmp(entry_name,"INT ",4) == 0)
  563.       {
  564.       id[0] = entry_name[4] ;
  565.       id[1] = entry_name[5] ;
  566.       entry_name += 6 ;
  567.       if (entry_name[0] == '/')
  568.      entry_name++ ;
  569.       }
  570.    else if (to_separator_line(-1))
  571.       {
  572.       id[0] = character(point+11) ;
  573.       id[1] = character(point+12) ;
  574.       }
  575.    point = start ;
  576.    c = entry_name[1] ;
  577.    if (entry_name[0] == 'A' && (c == 'X' || c == 'H' || c == 'L'))
  578.       {
  579.       entry_name += 2 ;
  580.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  581.      entry_name++ ;
  582.       if (entry_name[0] == '=')
  583.      entry_name++ ;
  584.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  585.      entry_name++ ;
  586.       if (c != 'L')
  587.      {
  588.          id[2] = entry_name[0] ;
  589.          id[3] = entry_name[1] ;
  590.      }
  591.       if (c == 'X')
  592.      {
  593.      id[4] = entry_name[2] ;
  594.      id[5] = entry_name[3] ;
  595.      entry_name += 4 ;
  596.      }
  597.       else
  598.      {
  599.      if (c == 'L')
  600.         {
  601.         id[2] = entry_name[0] ;
  602.         id[3] = entry_name[1] ;
  603.         }
  604.      entry_name += 2 ;
  605.      }
  606.       if (entry_name[0] == 'H')
  607.      entry_name++ ;
  608.       if (entry_name[0] == '/')
  609.      entry_name++ ;
  610.       }
  611.    if (index("ABCDES",entry_name[0]) && index("HILPSXF",entry_name[1]))
  612.       {
  613.       id[6] = entry_name[0] ;
  614.       c = id[7] = entry_name[1] ;
  615.       entry_name += 2 ;
  616.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  617.      entry_name++ ;
  618.       if (entry_name[0] == '=')
  619.      entry_name++ ;
  620.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  621.      entry_name++ ;
  622.       id[8] = entry_name[0] ;
  623.       id[9] = entry_name[1] ;
  624.       if (c != 'H' && c != 'L' && (c != 'F' || entry_name[2] != 'h'))
  625.      {
  626.      id[10] = entry_name[2] ;
  627.      id[11] = entry_name[3] ;
  628.      entry_name += 4 ;
  629.      }
  630.       else
  631.      entry_name += 2 ;
  632.       if (entry_name[0] == 'H')
  633.      entry_name++ ;
  634.       if (entry_name[0] == '/')
  635.      entry_name++ ;
  636.       }
  637.    if (entry_name[0] == '\"')
  638.       {
  639.       entry_name++ ;
  640.       strcpy(extra_string,entry_name) ;
  641.       last = index(extra_string,'\"') ;
  642.       if (last)
  643.      *last = '\0' ;
  644.       }
  645.    else
  646.       extra_string[0] = '\0' ;
  647.    return 0 ;
  648. }
  649.  
  650. /*=============================================================*/
  651. /*=============================================================*/
  652.  
  653. int hex2_to_int(c1,c2)
  654. char c1, c2 ;
  655. {
  656.    if (c1 >= '0' && c1 <= '9')
  657.       c1 -= '0' ;
  658.    else if (c1 >= 'A' && c1 <= 'F')
  659.       c1 = c1 - 'A' + 10 ;
  660.    else if (c1 >= 'a' && c1 <= 'f')
  661.       c1 = c1 - 'a' + 10 ;
  662.    else
  663.       return -1 ;
  664.    if (c2 >= '0' && c2 <= '9')
  665.       c2 -= '0' ;
  666.    else if (c2 >= 'A' && c2 <= 'F')
  667.       c2 = c2 - 'A' + 10 ;
  668.    else if (c2 >= 'a' && c2 <= 'f')
  669.       c2 = c2 - 'a' + 10 ;
  670.    else
  671.       return -1 ;
  672.    return 16*c1 + c2 ;
  673. }
  674.  
  675. /*=============================================================*/
  676. /*=============================================================*/
  677.  
  678. char hex_digit(val)
  679. int val ;
  680. {
  681.    if (val < 0)
  682.       return '-' ;
  683.    else if (val > 9)
  684.       return 'A' + val - 10 ;
  685.    else
  686.       return '0' + val ;
  687. }
  688.  
  689. /*=============================================================*/
  690. /*=============================================================*/
  691.  
  692. int scan_for_entry(entry,extra_str,first_entry)
  693. char *entry, *extra_str ;
  694. int *first_entry ;
  695. {
  696.    int ah, al, t1, t2, match, found ;
  697.    char buf[7] ;
  698.  
  699.    *first_entry = 0 ;
  700.    ah = hex2_to_int(entry[2],entry[3]) ;
  701.    while (1)
  702.       {
  703.       if (!to_separator_line(1))
  704.      return 0 ;    /* failed if hit end of file */
  705.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  706.      return 0 ;    /* failed if no longer on same interrupt */
  707.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  708.       if (t1 == ah)
  709.      break ;
  710.       else if (t1 > ah)
  711.      {
  712.      to_begin_line() ;
  713.      *first_entry = point ;
  714.      return 0 ;    /* no such entry */
  715.      }
  716.       }
  717.    nl_reverse() ;
  718.    *first_entry = point ;
  719.    found = 0 ;
  720.    al = hex2_to_int(entry[4],entry[5]) ;
  721.    while (1)
  722.       {
  723.       if (!to_separator_line(1))
  724.      return 0 ;    /* failed if hit end of file */
  725.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  726.      return 0 ;    /* failed if no longer on same interrupt */
  727.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  728.       if (t1 != ah)
  729.      return 0 ;    /* failed if no longer on same INT/AH combo */
  730.       t2 = hex2_to_int(character(point+5),character(point+6)) ;
  731.       if (t2 == al)
  732.      {
  733.      if (!found)
  734.         {
  735.         found = 1 ;
  736.         *first_entry = point ;
  737.         }
  738.      if (entry[6] != '-')
  739.         {
  740.         grab(point+7,point+12,buf) ;
  741.         match = strncmp(buf,entry+6,6) ;
  742.         if (match == 0)
  743.            {
  744.            *first_entry = point ;
  745.            break ;
  746.            }
  747.         else if (match > 0)
  748.            return 0 ;    /* no exact match, but return a partial match */
  749.         }
  750.      else
  751.         break ;
  752.      }
  753.       else if (t2 > al)
  754.      {
  755.      if (found)
  756.         break ;
  757.      else
  758.         {
  759.         to_begin_line() ;
  760.         *first_entry = point ;
  761.         return 0 ;    /* no such entry */
  762.         }
  763.      }
  764.       }
  765.    point = *first_entry ;    /* back to first matching entry */
  766.    
  767.    
  768.    return 1 ;            /* we were successful */
  769. }
  770.  
  771. /*=============================================================*/
  772. /*=============================================================*/
  773.  
  774. int goto_entry(entry_name)
  775. char *entry_name ;
  776. {
  777.    char int_id[13], extra_string[60] ;
  778.    int start = point, first_entry ;
  779.    int int_num, curr_int ;
  780.    char search_str[22] ;
  781.    
  782.    parse_int_name(entry_name,int_id,extra_string) ;
  783.    int_num = hex2_to_int(int_id[0],int_id[1]) ;
  784.    if (to_separator_line(-1))
  785.       {
  786.       if (character(point+11) == '-')
  787.      curr_int = -1 ;
  788.       else
  789.      curr_int = hex2_to_int(character(point+11),character(point+12)) ;
  790.       if (int_num <= 0)
  791.      point = 0 ;        /* go to top of file */
  792.       else
  793.      {
  794.      if (curr_int < 0)
  795.         point = 0 ;        /* go to top of file */
  796.      strcpy(search_str,"----------") ;
  797.      search_str[10] = hex_digit((int_num-1) / 16) ;
  798.      search_str[11] = hex_digit((int_num-1) % 16) ;
  799.      search_str[12] = '\0' ;
  800.      search( (int_num<=curr_int)?-1:1, search_str) ;
  801.      to_begin_line() ;
  802.      }
  803.       }
  804.    else
  805.       point = 0 ;
  806.    if (!scan_for_entry(int_id,extra_string,&first_entry))
  807.       {
  808.       say("%s not found.",entry_name) ;
  809.       if (first_entry)
  810.      {
  811.      mark = start ;
  812.      point = first_entry ;
  813.      }
  814.       else
  815.      point = start ;
  816.       }
  817.    if (has_arg)
  818.      iter = 1 ;                /* don't search repeatedly */
  819.    return 0 ;
  820. }
  821.  
  822. /*=============================================================*/
  823. /*=============================================================*/
  824.  
  825. command goto_int() on intlist_tab[FCTRL(12)]
  826. {
  827.    char entry_name[60], def_entry[60] ;
  828.    int start = point ;
  829.  
  830.    to_begin_line() ;
  831.    if (parse_string(1,"SeeAlso: ",NULL) != 0)
  832.       {
  833.       point += 9 ;        /* skip the SeeAlso: */
  834.       if (point < start)    /* if we were originally to the right of     */
  835.      point = start ;    /* current position, go back to original pos */
  836.       grab_int_reference(def_entry) ;
  837.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  838.       }
  839.    else if (line_has_see_also())
  840.       {
  841.       grab_int_reference(def_entry) ;
  842.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  843.       }
  844.    else
  845.       get_string(entry_name,"Goto Interrupt: ") ;
  846.    point = start ;
  847.    goto_entry(entry_name) ;
  848.    if (has_arg)
  849.       iter = 1 ;
  850. }
  851.  
  852. /*=============================================================*/
  853. /* Put the current buffer into IntList major mode           */
  854. /*=============================================================*/
  855.  
  856. command intlist_mode()
  857. {
  858.    mode_keys = intlist_tab ;
  859.    intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
  860.    delete_hacking_tabs = 0 ;
  861.    major_mode = strsave("IntList") ;
  862.    make_mode() ;
  863.    auto_indent = 0 ;
  864.    margin_right = 79 ;
  865.    want_backups = 1 ;
  866.    undo_size = 100000 ;     /* less than default 500,000 since list is so big */
  867. }
  868.  
  869. when_loading()
  870. {
  871.    char *curbuf ;
  872.  
  873.    want_backups = want_backups.default = 1 ;
  874.    strcpy(backup_name,"%pbak/%b%e") ;        /* put backups in BAK subdir */
  875.    one_window() ;
  876.    intlist_mode() ;
  877.    if (exist("interrup.1st"))
  878.       {
  879.       curbuf = bufname ;
  880.       bufname = "interrup.1st" ;
  881.       intlist_mode() ;
  882.       bufname = curbuf ;
  883.       }
  884. /* Epsilon v6.0+ */
  885.    strcpy(mode_end," %d%p %S") ;
  886. }
  887.  
  888. /*=============================================================*/
  889. /* automagically switch into interrupt list mode on .LST and .1ST files */
  890.  
  891. suffix_lst()   { intlist_mode(); }
  892. suffix_1st()   { intlist_mode(); }
  893.  
  894.  
  895.